package com.wifibrowser.wifi;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;

import com.wifibrowser.lib.Log;
import com.wifibrowser.utils.Utils;

public class WiFiScanService extends Service {
    private static final String TAG = "WiFiScanService";
    private IntentFilter mFilter;
    private BroadcastReceiver mReceiver;
    
    private AtomicBoolean mConnected = new AtomicBoolean(false);
    private Context mContext;
    private WifiManager mWifiManager;
    private Scanner mScanner;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "Service Create");
        mScanner = new Scanner();
        mWifiManager = (WifiManager) getSystemService(Activity.WIFI_SERVICE);
        mFilter = new IntentFilter();
        mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        mFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        mFilter.addAction(Intent.ACTION_SCREEN_ON);
        mContext = this.getApplicationContext();
        mReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                handleEvent(intent);
            }
        };
        mConnected.set(Utils.isHasWifiConnection(this));
        registerReceiver(mReceiver, mFilter);
    }

    private void handleEvent(Intent intent) {
        String action = intent.getAction();
        if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
            NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
            Log.d(TAG, "handleEvent: "+ WifiManager.NETWORK_STATE_CHANGED_ACTION);
            mConnected.set(info.isConnected());
            if (!info.isConnected()) {
                Utils.setIsServiceUpdate(this, true);
            }
        } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
            Log.d(TAG, "status: SCAN_RESULTS_AVAILABLE_ACTION");
        } else if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
            int status = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
                    WifiManager.WIFI_STATE_UNKNOWN);
            if (status == WifiManager.WIFI_STATE_DISABLED) {
                resetNotificationUpdateTime();
            }
        } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
            Log.d(TAG, "android.intent.action.SCREEN_ON");
        }
    }

    private void resetNotificationUpdateTime() {
        Log.d(TAG, "resetUpdateTime");
    }

    private List<AccessPoint> getAllAccessPoints() {
        List<AccessPoint> accessPoints = new ArrayList<AccessPoint>();
        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
        if (configs != null) {
            for (WifiConfiguration config : configs) {
                AccessPoint accessPoint = new AccessPoint(this, config);
                accessPoints.add(accessPoint);
            }
        }

        List<ScanResult> results = mWifiManager.getScanResults();
        if (results != null) {
            for (ScanResult result : results) {
                // Ignore hidden and ad-hoc networks.
                if (result.SSID == null || result.SSID.length() == 0
                        || result.capabilities.contains("[IBSS]")) {
                    continue;
                }

                if (result.frequency == 0) {
                    continue;
                }
                boolean found = false;
                for (AccessPoint accessPoint : accessPoints) {
                    if (accessPoint.update(result)) {
                        found = true;
                    }
                }
                if (!found) {
                    accessPoints.add(new AccessPoint(this, result));
                }
            }
        }
        return accessPoints;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        Log.d(TAG, "onStartCommand");
        mScanner.resume();
        boolean isHasWifiConnecton = Utils.isHasWifiConnection(this);
        if (intent != null) {
            //boolean isReboot = intent.getBooleanExtra(Constants.REBOOT_START,false);
            mConnected.set(isHasWifiConnecton);
        }
        return Service.START_STICKY;
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy");
        if (mReceiver != null) {
            unregisterReceiver(mReceiver);
        }
    }

    @SuppressLint("HandlerLeak")
	private class Scanner extends Handler {
        private int mRetry = 0;
        void resume() {
            if (!hasMessages(0)) {
                sendEmptyMessage(0);
            }
        }

        @Override
        public void handleMessage(Message msg) {
            if (mWifiManager.startScan()) {
                mRetry = 0;
            } else if (++mRetry >= 3) {
                mRetry = 0;
                return;
            }
            sendEmptyMessageDelayed(0, 1000 * 60);
        }
    }
}
